package com.wechat.page.contact.misc;

import com.swak.entity.Toggle;
import com.swak.fx.support.Display;
import com.swak.fx.support.ui.UI;
import com.swak.fx.support.ui.UIEvent;
import com.swak.fx.support.ui.UIIcon;
import com.swak.fx.support.ui.UIImage;
import com.swak.fx.support.ui.UILifecycle;
import com.swak.fx.support.ui.UITextFlow;
import com.swak.utils.StringUtils;
import com.wechat.dto.ContactDTO;
import com.wechat.page.comps.TextComp;

import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.text.TextAlignment;

/**
 * ContactThumb.
 * 
 * @author DELL
 */
public class ContactThumb extends GridPane implements TextComp, UILifecycle {

	public static final String SelectEvent = "Select.Event";
	public static final String RemoveEvent = "Remove.Event";

	private final String[] STYLE_CLASS = { "contact-thumb" };

	private UIIcon remove;
	private UIIcon select;
	private UIImage image;
	private UITextFlow name;

	public ContactThumb() {
		this.getStyleClass().addAll(STYLE_CLASS);

		this.image = new UIImage();
		this.name = new UITextFlow();

		this.init();
	}

	@Override
	public void initializeParts() {
		this.image.getStyleClass().add("contact-thumb__image");
		this.image.image(Display.logo());
		this.image.setPrefSize(40, 40);
		this.name.setPrefWidth(48);
		this.name.setMaxWidth(48);
		this.name.setTextAlignment(TextAlignment.CENTER);
		this.name.getStyleClass().add("contact-thumb__name");
		this.add(image, 0, 0);
		this.add(name, 0, 1);

		this.setPrefSize(54, 69);
		GridPane.setHgrow(this.image, Priority.ALWAYS);
		GridPane.setVgrow(this.image, Priority.NEVER);
		GridPane.setHalignment(this.image, HPos.CENTER);
		GridPane.setValignment(this.image, VPos.CENTER);
		GridPane.setMargin(this.image, new Insets(0, 0, 3, 0));

		GridPane.setFillHeight(this.name, false);
		GridPane.setHgrow(this.name, Priority.ALWAYS);
		GridPane.setVgrow(this.name, Priority.ALWAYS);
		GridPane.setHalignment(this.name, HPos.CENTER);
		GridPane.setValignment(this.name, VPos.CENTER);
	}

	@Override
	public void setupBindings() {
		UILifecycle.super.setupBindings();
		this.image.decorationProperty().bind(Bindings.createObjectBinding(() -> {
			boolean removeAble = this.removeAbleProperty.get();
			return removeAble ? this.createRemoveBtn() : null;
		}, this.removeAbleProperty));
		this.image.decorationProperty().bind(Bindings.createObjectBinding(() -> {
			boolean selectAble = this.selectAbleProperty.get();
			return selectAble ? this.createSelectBtn() : null;
		}, this.selectAbleProperty));
	}

	private UIIcon createRemoveBtn() {
		if (this.remove == null) {
			synchronized (ContactThumb.class) {
				if (this.remove == null) {
					this.remove = new UIIcon().Icon(UI.Icons.REMOVE);
					this.remove.setPrefWidth(16);
					this.remove.Round();
					this.remove.getStyleClass().add("contact-thumb__remove");
					this.remove.addEventHandler(MouseEvent.MOUSE_CLICKED, this.removeHandler);
				}
			}
		}
		return this.remove;
	}

	private UIIcon createSelectBtn() {
		if (this.select == null) {
			synchronized (ContactThumb.class) {
				if (this.select == null) {
					this.select = new UIIcon().Icon(UI.Icons.SUCCESS);
					this.select.setPrefWidth(16);
					this.select.Round();
					this.select.getStyleClass().add("contact-thumb__select");
					this.select.setVisible(false);
				}
			}
		}
		return this.select;
	}

	@Override
	public void setupValueChangedListeners() {
		UILifecycle.super.setupValueChangedListeners();
		this.contactProperty().addListener((ob, o, n) -> this.onContactChange(n));
		this.selectedProperty.addListener((ob, o, n) -> {
			if (n && this.select != null) {
				this.select.setVisible(true);
			} else if (this.select != null) {
				this.select.setVisible(false);
			}
		});
	}

	private void onContactChange(ContactDTO contact) {
		this.buildTextContent(this.name, StringUtils.defaultIfBlank(contact.getAlias(), contact.getNickName()));
	}

	@Override
	public void setupEventHandlers() {
		UILifecycle.super.setupEventHandlers();
		this.addEventHandler(MouseEvent.MOUSE_CLICKED, this.selectHandler);
	}

	private void onSelect(MouseEvent event) {
		event.consume();
		this.selectedProperty.set(!this.selectedProperty.get());
		Toggle<ContactDTO> select = new Toggle<ContactDTO>().setValue(this.contactProperty.get())
				.setActive(this.selectedProperty.get());
		this.fireEvent(UIEvent.of().setCmd(SelectEvent).setData(select));
	}

	private void onRemove(MouseEvent event) {
		event.consume();
		this.fireEvent(UIEvent.of().setCmd(RemoveEvent).setData(this.contactProperty.get()));
	}

	@Override
	public void initializeFinish() {
		UILifecycle.super.initializeFinish();
	}

	// ================================================================================
	// Properties
	// ================================================================================
	private final ObjectProperty<ContactDTO> contactProperty = new SimpleObjectProperty<>();
	private BooleanProperty removeAbleProperty = new SimpleBooleanProperty(false);
	private BooleanProperty selectAbleProperty = new SimpleBooleanProperty(false);
	private BooleanProperty selectedProperty = new SimpleBooleanProperty(false);

	public ObjectProperty<ContactDTO> contactProperty() {
		return contactProperty;
	}

	public BooleanProperty removeAbleProperty() {
		return removeAbleProperty;
	}

	public BooleanProperty selectAbleProperty() {
		return selectAbleProperty;
	}

	// ================================================================================
	// Event
	// ================================================================================
	EventHandler<MouseEvent> selectHandler = (e) -> this.onSelect(e);
	EventHandler<MouseEvent> removeHandler = (e) -> this.onRemove(e);
}
